#ifndef _spi_h
#define _spi_h
#ifdef __cplusplus
extern "C" {
#endif

#include "AVRcommon.h"
#include <avr/pgmspace.h>
#include <stdio.h>

// Debug Mode (Enables USART Messages and More)...
//#define DEBUG 0



extern uint FLASHSIZE_KB;			/* Detected and updated when user reads signature byte 2(3rd byte) */
extern bool USE_LOWER_DELAY;		/* If non-zero, lower delay is used when using readWriteSPIByte() */

//! Target Control and Communication Functions:
void activateTargetControl(void);	/* Asserts reset on the target */
void releaseTargetControl(void);	/* Deasserts reset on the target */

void resetTarget(void);

void sendPacket(char *a, char *b, char *c, char *d);

//! Lower Level Functions (private):
void spiInitialize(void);			/* Do not use: Helper of activateTargetControl() */
void spiDeactivate(void);			/* Do not use: Helper of releaseTargetControl() */
char readWriteSPIByte(char byte);	/* Do not use: Helper of sendPacket() */

//! Pre:	None
//! Post:	Returns true if target can communicate with this programmer.
//!			During the process, enable programming command is sent to target
//!			and signature is read to see if it is 0x95 (Atmel Family)
bool checkTargetCommunication();


bool checkSPI();					/* Do not use: Helper of tryDifferentSPISpeeds() */
bool tryDifferentSPISpeeds();		/* Do not use: Helper of checkTargetCommunication */


bool enableProgramming(void);
bool eraseChip(void);
bool targetReadyForNextCommand(void);

bool writeEEPROM(uint address, char data);
bool readEEPROM(uint address, char* data);

void loadExtendedAddressByte(char byte);
//! used for chips over 64K memory.  It can be 0-3 to address 0-256K Memory

void loadProgramMemoryPage(unsigned char addressLSB, int word);
//! Page is loaded from address 0-PAGESIZE word by word
//! Caller should load 0-Page Size in Words

void performPageWrite(unsigned int address);
//! Once entire page is loaded, page can be written to memory
//! Address is the full address in bytes
//! Atmega grabs BITS15:BIT7 (Page Number) to write the page to the FLASH.
//! Therefore, the lowest 7 bits are not used.
//! For chips greater than 64K memory, the extended address byte must be loaded first

unsigned int readProgramMemory(unsigned int address);
//! Returns a word from any flash address region.  Address is in WORDS not bytes
//! To address regions outside of 64K, use loadProgramMemoryPage() first



char readLockByte(void);
char readFuseHighByte(void);
char readFuseLowByte(void);
char readExtendedFuseByte(void);
char readCalibrationByte(void);

bool writeLockByte(char byte);
bool writeFuseHighByte(char byte);
bool writeFuseLowByte(char byte);
bool writeExtendedFuseByte(char byte);

char readSignatureByte(char byteNumber);
//! There are 3 signature bytes to choose from 0-2







#ifdef __cplusplus
}
#endif
#endif
